<?php
/**
 * This file is part of DomMvc.
 * 
 * DomMvc is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomMvc is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomMvc.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
 * Can be used to create multilanguage website.
 * 
 * 
 * Loads language from conf dir with file name lang.KEY.php
 * File should be structured like this
 * <code>
 * <?php
 * $LANGUAGE = array(
 * 		String key => String translation
 * );
 * ?>
 * </code>
 * Replacements can be written as [$REPLACEMENT_NAME]. Sample: 'Hello, [$firstName]'
 * 
 * 
 * Usage:
 * <code>
 * // basic usage. initialization.
 * DomLanguageController::c('default')
 * 	->addLanguage( array('Est') )
 * 	->addLanguage( array('Eng') )
 *  ->setDefaultLanguage('Eng')
 *  ->init();
 * 
 * // get all usable languages
 * debug(DomLanguageController::c()::getLanguages());
 * 
 * // get sentence (See also using through Smarty(DomView) )
 * debug( DomLanguage::getl('greeting', array('firstName' => 'Oliver') ) ); // greeting => 'Hello, [$firstName]!' will be 'Hello, Oliver!'
 * // or
 * debug( lang('greeting', array('firstName' => 'Oliver') ) ); // greeting => 'Hello, [$firstName]!' will be 'Hello, Oliver!'
 * </code>
 * It automatically uses $_GET['lang'] variable to change current language. If $_GET['lang'] value is not found in added languages default language will be used.
 * Also if language is changed using $_GET['lang'] it is stored in session and afterwards that language will be used as current.
 * 
 * 
 * Relation to Smarty(DomView):
 * <ul>
 * <li>See Smarty function lang. (Usage sample: {lang key=KEY REPLACEMENT_NAME=value firstName=$userFirstName})</li>
 * <li>Also DomView adds $lang variable. (Usage sample: {$lang.KEY}). Notice that replacements cannot be used this way, but its faster.</li>
 * </ul>
 * @package DomMvc
 */
class DomLanguageController {
	
	/**
	 * Change this to some string if you need to use multiple sites with different language settings on same domain.
	 *
	 * @var String
	 */
	private $sessionId;
	/**
	 * @var Array
	 */
	private $languages;
	/**
	 * @var String
	 */
	private $defaultLanguage;
	/**
	 * @var String
	 */
	private $currentLanguage;
	/**
	 * @var DomLanguageController
	 */
	private static $self;
	
	const SESSION_VAR = 'DomSiteCurrentLanguage';
	
	/**
	 * To get language controller use $lang = DomLanguageController::c(). Uses singelton pattern.
	 * @param String $sessionId
	 */
	private function __construct( $sessionId = 'default' ) {
		$this->sessionId = $sessionId;
	}
	
	/**
	 * @param String $sessionId
	 * @return DomLanguageController
	 */
	public static function c( $sessionId = 'default' ) {
		if( self::$self === NULL ) {
			$className = __CLASS__;
			self::$self = new $className( $sessionId );
		}
		return self::$self;
	}
	
	/**
	 * Adds new language. Use link and media if you want to make easy language menu for website.
	 *
	 * @param String $key
	 * @param String $link
	 * @param String $media
	 * @return DomLanguageController
	 */
	public function addLanguage( $key, $link = '', $media = '' ) {
		$this->languages[$key] = array(
			'name' => $name,
			'media' => $iconUrl,
			'link' => $link.'&lang='.$key,
		);
		
		if( $this->defaultLanguage === NULL )
			$this->defaultLanguage = $key;
			
		return $this;
	}
	/**
	 * Sets default language
	 * @param String $key
	 * @return DomLanguageController
	 */
	public function setDefaultLanguage( $key ) {
		if( isset($this->languages[$key]) )
			$this->defaultLanguage = $key;
		else
			throw new RuntimeException('Can\'t set default language to <b>'.$key.'</b>. It is not added as possible language!');
		return $this;
	}
	/**
	 * Initializes language controller. After languages are added use this to load current language. Do this before using any language features.
	 *
	 * @return DomLanguageController
	 */
	public function init() {
		
		if( isset($_GET['lang']) === true && isset($this->languages[$_GET['lang']]) === true ) {
			$currentLang = $_GET['lang'];
			$_SESSION[SESSION_VAR][$this->sessionId] = $_GET['lang']; 
		
		} else if( isset($_SESSION[SESSION_VAR][$this->sessionId]) ) {
			$currentLang = $_SESSION[SESSION_VAR][$this->sessionId];
		
		} else {
			$currentLang = $this->defaultLanguage;
		}
		
		$this->setCurrentLanguage( $currentLang );
		return $this;
	}
	/**
	 * @return DomLanguage
	 */
	public function getCurrentLanguage() {
		return $this->currentLanguage;
	}
	/**
	 * @return Array
	 */
	public function getLanguages() {
		return $this->languages;
	}
	/**
	 * @param String $key
	 */
	public function setCurrentLanguage( $key ) {
		$this->currentLanguage = $this->loadLanguage( $key );
		$_SESSION[SESSION_VAR][$this->sessionId] = $key;
	}
	
	/**
	 * Loads language from file. 
	 * 
	 * File should be in conf dir and named lang._KEY_.php
	 * Language must be added first with addLanguage method.
	 *
	 * @param String $key
	 * @return DomLanguage
	 */
	private function loadLanguage( $key ) {
		if( $this->languages[$key]['object'] instanceOf DomLanguage )
			return $this->languages[$key]['object'];
		
		if( isset($this->languages[$key]) === true ) {
			require(DOM_CONF_DIR_PATH . 'lang.'.$key.'.php');
			$this->languages[$key]['object'] = new DomLanguage( $key, $LANGUAGE );
			return $this->languages[$key]['object'];
		
		} else {
			throw new RuntimeException('Language '.$key.' doesn\'t exist!');
		}
	}
	
	
}

/**
 * @author Oliver Leisalu
 * @package DomController
 */
class DomLanguage {
	
	public $key;
	
	public $name;
	
	public $language = array();
	
	public function __construct( $key, array $language ) {
		$this->key = $key;
		$this->language = $language;
	}
	
	/**
	 * Returns all current language sentences. Notice that no replacements are made!
	 * @return Array
	 */
	public function getAllLang() {
		return $this->language;
	}
	
	/**
	 * Shorthand for DomLanguage->getLang. Use this to write less code :)
	 *
	 * @param String $key
	 * @param Array $replacements
	 * @return String
	 */
	public static function getl( $key, array $replacements = array() ) {
		return DomLanguageController::c()->getCurrentLanguage()->getLang( $key, $replacements );
	}
	
	/**
	 * Returns current language key
	 * @return String
	 */
	public static function getk() {
		return DomLanguageController::c()->getCurrentLanguage()->key;
	}

	/**
	 * Returns language word
	 *
	 * @param String $key
	 * @param array $replacements
	 * @return String
	 */
	public function getLang( $key, array $replacements = array() ) {
		if( isset($this->language[$key])) {
			$sentence = $this->language[$key];
			if( empty($replacements) === false ) {
				foreach( $replacements as $key => $replacement )
					$sentence = str_replace('[$'.$key.']', $replacement, $sentence);
			}
			return $sentence;
		} else {
			throw new RuntimeException('Undefined language sentence: <b>'.$key.'</b>');
		}
	}
	
	/**
	 * Translate text using google translate.
	 * Notice that this method sends query to google ajax api server and gets translation back. Meaning, its slow!
	 * 
	 * Usage sample: 
	 * DomLanguage::translate('Hello','en','et);
	 * DomLanguage::translate(array(*hellow','Goodbye'),'en','et);
	 * 
	 * @param String $text
	 * @param String $fromLanguage
	 * @param String $toLanguage
	 * @return String
	 */
	public static function translate( $text, $fromLanguage, $toLanguage ) {
		
		//setting language pair
		$multpleTexts = is_array($text);
		if( $multpleTexts === true ) {
			$src_texts_query = '';
			foreach( $text as $t ) {
				$src_texts_query .= '&q='.urlencode($t);
			}
			
		} else {
			$src_texts_query = '&q='.urlencode($text);
		}
		$url = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0".$src_texts_query."&langpair=".urlencode($fromLanguage.'|'.$toLanguage);
		
		
		// sendRequest
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_REFERER, SITE_URL );
		$body = curl_exec($ch);
		curl_close($ch);
		
		// now, process the JSON string
		$json = json_decode($body, true);

		if ($json['responseStatus'] != 200)
			throw new RuntimeException( $json['responseDetails'].'<br><b>Language pair:</b> '. $fromLanguage.'|'.$toLanguage.' <br> <b>Text:</b> '.$text.'<br>',$json['responseStatus']);
		
		
		
		
		$return_array = array();
		if( isset($json['responseData']['translatedText']) ) {
			$return_array[] = $json['responseData']['translatedText'];
		} else {
			foreach( $json['responseData'] as $result) {
				if( $result['responseStatus'] == 200)
					$return_array[] = $result['responseData']['translatedText'];
				else
					$return_array[] = $result['responseDetails'];
			}
		}
		
		if( $multpleTexts === true ) {
			return $return_array;
		} else {
			return array_pop($return_array);
		}
	}
	
}

function lang( $key, array $replacements = array() ) {
	return DomLanguage::getl( $key, $replacements );
}
?>